package fiuba.algo3.control;

import java.io.IOException;
import java.util.ArrayList;
import java.util.ListIterator;

import fiuba.algo3.modelo.Dificultad;
import fiuba.algo3.modelo.Direccion;
import fiuba.algo3.modelo.Estado;
import fiuba.algo3.modelo.Partida;
import fiuba.algo3.modelo.Posicion;
import fiuba.algo3.modelo.mapa.*;
import fiuba.algo3.modelo.vehiculo.*;
import fiuba.algo3.persistencia.Guardador;
import fiuba.algo3.persistencia.Restaurador;
import fiuba.algo3.usuario.Usuario;
import fiuba.algo3.usuario.UsuarioInexistenteException;
import fiuba.algo3.usuario.UsuariosExistentes;
import fiuba.algo3.vista.JFPrincipal;


public class Controlador{

	private Juego juego;
	private JFPrincipal framePrincipal;
	
	
	// Para los tests
	public Controlador(){
	
	}
	
	public Controlador(JFPrincipal principal){
		this.framePrincipal = principal;
	}



	public Estado moverVehiculoHacia(Direccion direccion){
		Estado estado = juego.moverVehiculoHacia(direccion);
		if(estado != Estado.EN_CURSO){
	
			if (estado == Estado.GANADA){
				this.actualizarUsuario();
				this.framePrincipal.partidaGanada();
			}else{
				this.framePrincipal.partidaPerdida();
			}
		}
		return estado;
	}
	
	
	private void actualizarUsuario() {
		UsuariosExistentes usuarios = new UsuariosExistentes();
		try {
			usuarios.actualizarUsuario(juego.getUsuario().getNombre(), juego.getPartida().getPuntaje());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UsuarioInexistenteException e) {
			e.printStackTrace();
		}
	}

	
	public void nuevoJuego(Usuario usuario, Dificultad dificultad, TipoDeVehiculo unTipo) throws IOException {
		juego = new Juego(usuario);
		juego.nuevaPartida(dificultad, unTipo);
	}
	
	
	public void reanudarPartida(String nombreDeUsuario) throws IOException {
		juego = new Juego(nombreDeUsuario);
		Partida partida = Restaurador.levantarPartidaDe(nombreDeUsuario+"_partida.xml");
		juego.setPartidaRecuperada(partida);
	}
	
	
	public void guardarPartida() throws IOException{
		Partida partida = juego.getPartida();
		String nombreDeUsuario = juego.getUsuario().getNombre();
		Guardador.guardar(partida, nombreDeUsuario);
	}

	
	public Mapa getMapa() {
		return juego.getPartida().getMapa();
	}

	public TipoDeVehiculo getTipoDeVehiculo() {
		return juego.getPartida().getVehiculo().getTipo();
	}

	public Posicion getPosicionVehiculo() {
		return juego.getPartida().getVehiculo().getPosicionActual();
	}

	public Posicion getPosicionMeta() {
		return juego.getPartida().getPosicionDeLaMeta();
	}

	public Juego getJuego() {
		
		return juego;
	}
	
	public String getMovimientosRestantesComoString(){
		return new Integer(juego.getPartida().getCantidadDeMovimientosRestantes()).toString();
	}
	
	public ArrayList<String> getRanking(){
		String	usuarioConPuntaje = new String();
		int contador = 0;
		ArrayList<String> ranking = new ArrayList<String>();
		UsuariosExistentes usuariosExistentes = new UsuariosExistentes();
		
		ListIterator<Usuario> iterador = usuariosExistentes.getRankingUsuarios().listIterator();
		while ((iterador.hasNext()) && (contador < 10)){
			Usuario usuarioActual = iterador.next();
			Integer puntajeAux = usuarioActual.getPuntajeMaximo();
			usuarioConPuntaje = usuarioActual.getNombre() + " : " + puntajeAux.toString();
			ranking.add(usuarioConPuntaje);
			contador++;
		}
		return ranking;
	}

	public boolean existenUsuarios() {
		return !(new UsuariosExistentes().isEmpty());
	}
	
}